package memento;

import java.io.*;

/**
 * 记录一个对象的状态。
 * 场景
 * 比如一个坦克向左 另一个向右 瞬时记录下来。 然后存到某一个对象里面。
 * 经常配合命令模式
 *
 * 用这个类记录完所有对象的状态然后序列化 存盘到硬盘
 *
 * 对象序列化和对象持久化
 * 被序列化的对象必须实现 Serializable 接口。
 *
 * 第二种方式可以直接把对象写出去
 *
 * ObjectInputStream
 * 通过它的 write 可以吧 对象写出去
 * 如果对象里面还有对象，先把对象本身写出去在把内部对象也写出去。
 *
 * 注意 ObjectOutputStream 先写的哪个对象
 *     ObjectInputStream 就要先读哪个对象
 *
 *
 * 网络传输主要用protoBuf
 */
public class Memento {
    public static void main(String args[]){
        System.out.println("Memento");
        S s = new S();
        File file = new File("./file.txt");
        ObjectOutputStream outputStream = null;
        try {
            outputStream = new ObjectOutputStream(new FileOutputStream(file));
            outputStream.writeObject(s);
//            outputStream.close();
        }catch (Exception e){

        } finally {
            try{
                outputStream.close();
            }catch (Exception e){

            }
        }

        // 在读取出来
        ObjectInputStream objectInputStream = null;
        try {
            objectInputStream = new ObjectInputStream(new FileInputStream(file));
            S sa = (S)objectInputStream.readObject();
            System.out.println(sa);
        }catch (Exception e){

        } finally {
            try{
                objectInputStream.close();
            }catch (Exception e){

            }
        }
    }
}

class L implements Serializable{ // 内部类也必须实现 Serializable

}

/**
 * 不管用那种方式被写出去的类一定要实现Serializable 这个标示接口否则报错。内部的类同样也需要实现Serializable
 * 或者在属性前面加 transient 透明的明确告诉写出不写这个属性 写到硬盘不需要管被transient修饰的属性。 如果非要就必须要实现Serializable这个接口
 * 如果序列化transient 在回来就没了慎用。 内部所有的引用都需要序列化。
 */
class S implements Serializable{
// private  transient S s = new S();
    private L l = new L();
}